// 定义一个结构体
#[derive(Debug)]
struct User {
    active : bool,
    name : String,
    sex : i8,
}

// 定义一个矩形结构体
// 派生Debug特性
#[derive(Debug)]
struct Rectangle {
    width: u32,
    height: u32,
}

// imp块与结构体相关
impl Rectangle {

    // 方法的第一个参数是&self
    fn area(&self) -> u32 {
        self.width * self.height
    }

    // 带有更多参数，例如判断该矩形是否包含另一个矩形
    fn can_hold(&self, other: &Rectangle) -> bool {
        self.width > other.width && self.height > other.height
    }

    // 关联函数，用来构造一个特殊的矩形 正方形
    fn square(size: u32) -> Self {
        Self {
            width: size,
            height: size,
        }
    }
}

// 没有字段的元组结构体
struct Color(i32, i32, i32);
struct Point(i32, i32, i32);

fn main() {
    // 实例化一个用户，字段顺序可以和定义不一样
    let mut user = User {
        name: String::from("张三"),
        sex: 0,
        active: false,
    };
    user.name = String::from("李四");

    println!("{},{},{}", user.active, user.name, user.sex);

    let name = String::from("liergou");
    let sex = 1;
    let user = build_user(name, sex);
    println!("{},{},{}", user.active, user.name, user.sex);

    // 结构体更新语法
    let user = User {
        active: false,
        name: String::from("cargo"),
        sex: 1,
    };

    let user = update_user(user, String::from("wangwu"));
    println!("{:?}", user);

    let original_point = Point(0, 0, 0);
    let black = Color(0, 0, 0);
    println!("{},{},{}", original_point.0, original_point.1, original_point.2);
    println!("{},{},{}", black.0, black.1, black.2);

    let scale = 2;
    let rect1 = Rectangle{
        width: 10,
        // dgb!输出源码所在的行，用于调试
        height: dbg!(20 * scale),
    };
    // let area = area(&rect1);
    // println!("矩形:{:?},面积为：{}", rect1, area);
    // 调用结构体的方法
    println!("矩形:{:?},面积为：{}", rect1, rect1.area());


    let rect1 = Rectangle{
        width: 10,
        height: 20,
    };
    let rect2 = Rectangle{
        width: 8,
        height: 4,
    };
    println!("{}", rect1.can_hold(&rect2));
    println!("{}", rect2.can_hold(&rect1));

    // 关联函数
    let square1 = Rectangle::square(100);
    println!("正方形面积为:{}", square1.area());
}

fn area(rect: &Rectangle) -> u32 {
    rect.width * rect.height
}

// 函数体最后构造一个结构体实例，返回这个实例
fn build_user(name: String, sex: i8) -> User {
    User {
        active: false,
        // 简写语法
        sex,
        name,
    }
}

fn update_user(user: User, name: String) -> User {
    User {
        name,
        // 必须放在最后
        ..user
    }
}